home *** CD-ROM | disk | FTP | other *** search
/ Amiga News 95 / Amiga News 95.iso / dpat / dpat31 / iobject / sources.lha / sources / TextArea.c < prev   
Encoding:
C/C++ Source or Header  |  1993-03-23  |  8.5 KB  |  404 lines

  1. // TextArea.c V0.25
  2. // Zone de texte avec scrolling
  3. // (C) 1992 par Christophe PASSUELLO
  4. // Tue Mar 16 18:49:01 1993
  5.  
  6.  
  7. #include <exec/types.h>
  8. #include <exec/memory.h>
  9. #include <mytypes.h>
  10. #include <graphics/text.h>
  11. #include <graphics/rastport.h>
  12. #define  INTUITION_PREFERENCES_H 0
  13. #include "IObject_priv.h"
  14.  
  15.  
  16. IMPORT CPTR DiskfontBase;
  17. IMPORT UBYTE Pen1, Pen2;
  18.  
  19. /* definition de la structure TextArea */
  20. struct TextArea
  21. {
  22.     UWORD  LeftEdge, TopEdge;
  23.     UWORD  Width, Height;
  24.     struct RastPort *RPort;
  25.     STRPTR LabelText;
  26.     UBYTE  FPen, BPen;
  27.     UBYTE  LineHeight;
  28.     UBYTE  WrMask;
  29.     UWORD  Flags;
  30.     UWORD  ClassFlags;
  31.     struct Box TextBox;
  32.     struct TextFont *Font;
  33.     UWORD NbLine, NbCol;
  34.     UWORD CurLine, CurCol;
  35. };
  36.  
  37.  
  38. /* Methodes pour la classe TextArea */
  39. VOID Locate(struct TextArea *, UWORD, UWORD);
  40. VOID ScrollTextArea(struct TextArea *, WORD);
  41. VOID FastScroll(struct TextArea *, WORD);
  42. UWORD ClipString(struct TextFont *, char *, UWORD, UWORD);
  43. UWORD StringLength(struct TextFont *, char *, UWORD);
  44. UWORD GetCurrentWidth(struct TextArea *);
  45. VOID LineFeed(struct TextArea *area);
  46.  
  47.  
  48. /* fonctions privees */
  49. PRIVATE VOID LowLevelText(struct TextArea *, char *, UWORD);
  50. PRIVATE VOID TextClip(struct TextArea *, char *, UWORD);
  51. PRIVATE UWORD SearchCtrl(char *, UWORD);
  52. PRIVATE UWORD DoCtrl(struct TextArea *, char *);
  53.  
  54.  
  55. /**********************************************/
  56. /* implementation des methodes pour TextArea    */
  57. /**********************************************/
  58.  
  59.  
  60. //
  61. // Cree une zone texte
  62. //
  63. struct TextArea *CreateTextArea(struct NewTextArea *newarea, struct RastPort *rp)
  64. {
  65.     struct TextArea *area;
  66.  
  67.     if (area = AllocMem( sizeof(struct TextArea), MEMF_CLEAR|MEMF_PUBLIC))
  68.     {
  69.         area->RPort = rp;
  70.  
  71.         COPY_BOX(&area->LeftEdge, &newarea->LeftEdge);
  72.         COPY_BOX(&area->TextBox, &newarea->LeftEdge);
  73.         AdjustBox(&area->TextBox, FALSE);
  74.  
  75.         area->Flags = newarea->Flags;
  76.         area->ClassFlags = newarea->ClassFlags;
  77.         area->LabelText = newarea->LabelText;
  78.         area->Font = LoadFont(newarea->Font);
  79.         area->FPen = newarea->FrontPen;
  80.         area->BPen = newarea->BackPen;
  81.         area->LineHeight = newarea->InterLine + area->Font->tf_YSize;
  82.  
  83.         area->NbCol  = area->TextBox.w / area->Font->tf_XSize;
  84.         area->NbLine = (area->TextBox.h + 1) / area->LineHeight;
  85.  
  86.         ClearTextArea(area);
  87.  
  88.         // affiche le label
  89.         {
  90.             struct TextEnv env;
  91.  
  92.             SaveTextEnv(rp, &env);
  93.             SetAPen(rp, (area->Flags & LABEL_PEN2) ? Pen2 : Pen1);
  94.             SetFont(rp, area->Font);
  95.             PrintLabelText(rp, &area->LeftEdge, area->LabelText, area->Flags & LABEL_MASK);        //MASK
  96.             RestoreTextEnv(rp, &env);
  97.         }
  98.     }
  99.     return (area);
  100. }
  101.  
  102.  
  103. //
  104. // Libere le TextArea
  105. //
  106. VOID FreeTextArea(struct TextArea *area)
  107. {
  108.     CloseFont(area->Font);
  109.     FreeMem(area, sizeof(struct TextArea) );
  110. }
  111.  
  112.  
  113. //
  114. // Efface la TextArea
  115. //
  116. VOID ClearTextArea(struct TextArea *area)
  117. {
  118.     FillBox(&area->LeftEdge, area->RPort, area->BPen);
  119.     Draw3DBox(&area->LeftEdge, area->RPort, BOX_1IN);
  120.     area->CurCol = area->CurLine = 0;
  121. }
  122.  
  123.  
  124. //
  125. // Change les couleurs du TextArea
  126. //
  127. VOID SetTextAreaPen(struct TextArea *area, UBYTE fg, UBYTE bg)
  128. {
  129.     area->FPen = fg;
  130.     area->BPen = bg;
  131. }
  132.  
  133.  
  134. /************************************/
  135. /* Scroll le TextArea de off lignes */
  136. /************************************/
  137. VOID FastScroll(struct TextArea *area, WORD off)
  138. {
  139.     WORD dy;
  140.     UWORD x, y;
  141.  
  142.     dy = off * area->LineHeight;
  143.     y = area->TextBox.y;        x = area->TextBox.x;
  144.     ScrollRaster(area->RPort, 0, dy, x, y, x+area->TextBox.w-1, y+area->TextBox.h-1);
  145. }
  146.  
  147.  
  148. /************************************/
  149. /* Scroll le TextArea de off lignes */
  150. /************************************/
  151. VOID ScrollTextArea(struct TextArea *area, WORD off)
  152. {
  153.     WORD dy, YSize, nb;
  154.     UWORD x, y;
  155.     UBYTE    bpen;
  156.  
  157.     YSize = area->LineHeight;
  158.     nb = ABS( off );
  159.     dy = SIGN(off);
  160.  
  161.     if (area->ClassFlags & TAF_SMOOTH_SCROLL)
  162.         nb *= YSize;
  163.     else
  164.         dy *= YSize;
  165.  
  166.     bpen = area->RPort->BgPen;
  167.     SetBPen(area->RPort, area->BPen);
  168.     y = area->TextBox.y;        x = area->TextBox.x;
  169.     while (nb-- > 0)
  170.         ScrollRaster(area->RPort, 0, dy, x, y, x+area->TextBox.w-1, y+area->TextBox.h-1);
  171.  
  172.     SetBPen(area->RPort, bpen);
  173. }
  174.  
  175.  
  176. /********************************************/
  177. /* Calcule la taille en pixels d'une chaine */
  178. /********************************************/
  179. UWORD StringLength(struct TextFont *CurrentFont, char *s, UWORD len)
  180. {
  181.     UWORD width, *space;
  182.     UBYTE car, lochar;
  183.  
  184.     width = 0;
  185.     if (CurrentFont->tf_Flags & FPF_PROPORTIONAL)
  186.     {        /* la fonte est proportionnelle */
  187.         space = CurrentFont->tf_CharSpace;
  188.         lochar = CurrentFont->tf_LoChar;
  189.  
  190.         while (len-- > 0)
  191.         {
  192.             car = *(s++);
  193.             if (car < lochar)
  194.                 car = lochar;
  195.  
  196.             width += space[car-lochar];
  197.         }
  198.     }
  199.     else
  200.         width = len * CurrentFont->tf_XSize;
  201.  
  202.     return (width);
  203. }
  204.  
  205.  
  206. /******************************************/
  207. /* Fonction pour clipper une chaine       */
  208. /* Renvoie le taille de la chiane clippee */
  209. /******************************************/
  210. UWORD ClipString(struct TextFont *CurrentFont, char *s, UWORD len, WORD widthmax)
  211. {
  212.     UWORD *space, length;
  213.     UBYTE car, lochar;
  214.  
  215.     if (CurrentFont->tf_Flags & FPF_PROPORTIONAL)
  216.     {
  217.         // la fonte est proportionnelle
  218.         space = CurrentFont->tf_CharSpace;
  219.         lochar = CurrentFont->tf_LoChar;
  220.         length = 0;
  221.  
  222.         while (len-- > 0)
  223.         {
  224.             car = *(s++);
  225.             if (car < lochar)
  226.                 car = lochar;
  227.  
  228.             widthmax -= space[car-lochar];
  229.             if (widthmax < 0)
  230.                 break;
  231.  
  232.             length++;
  233.         }
  234.         return (length);
  235.     }
  236.     else
  237.         return ( MIN(len, widthmax / CurrentFont->tf_XSize) );
  238. }
  239.  
  240.  
  241. /*************************************/
  242. /* Fonction pour afficher une chaine */
  243. /*************************************/
  244. VOID TAPrint(struct TextArea *area,char *s)
  245. {
  246.     char *ptr, car;
  247.     UWORD len, clen;
  248.  
  249.     len = strlen(s);
  250.  
  251.     while (len > 0)
  252.     {
  253.         clen = SearchCtrl(s, len);
  254.         if (clen)
  255.         {
  256.             TextClip(area, s, clen);
  257.             s += clen;
  258.             len -= clen;
  259.             if (len == 0)
  260.                 break;
  261.         }
  262.         clen = DoCtrl(area, s);
  263.         /* saute le code de controle */
  264.         len -= clen;
  265.         s += clen;
  266.     }
  267. }
  268.  
  269.  
  270. /*********************************************************/
  271. /* Fonction pour afficher une chaine avec retour chariot */
  272. /*********************************************************/
  273. VOID TAPuts(struct TextArea *area,char *s)
  274. {
  275.     TAPrint(area, s);
  276.     LineFeed(area);
  277. }
  278.  
  279.  
  280. /****************************************************/
  281. /* Renvoie le nombre de pixels de la ligne courante */
  282. /****************************************************/
  283. UWORD GetCurrentWidth(struct TextArea *area)
  284. {
  285.     if (area->Font->tf_Flags & FPF_PROPORTIONAL)
  286.         return (area->TextBox.w - area->CurCol);
  287.     else
  288.         return (area->TextBox.w - area->CurCol * area->Font->tf_XSize);
  289. }
  290.  
  291.  
  292. /********************************************/
  293. /* Cherche le premier caractere de controle */
  294. /********************************************/
  295. PRIVATE UWORD SearchCtrl(char *s, UWORD len)
  296. {
  297.     UWORD clen;
  298.  
  299.     #define LF    0x0a
  300.  
  301.     clen = 0;
  302.     while (len > 0)
  303.     {
  304.         if ( *(s++) == LF )
  305.             break;
  306.         clen++;
  307.         len--;
  308.     }
  309.     return( clen );
  310. }
  311.  
  312.  
  313. /********************************************/
  314. /* Cherche le premier caractere de controle */
  315. /********************************************/
  316. PRIVATE UWORD DoCtrl(struct TextArea *area, char *s)
  317. {
  318.     LineFeed(area);
  319.     return ( 1 );
  320. }
  321.  
  322.  
  323. /********************/
  324. /* Passe a la ligne */
  325. /********************/
  326. VOID LineFeed(struct TextArea *area)
  327. {
  328.     if (area->CurLine >= area->NbLine)
  329.     {
  330.         ScrollTextArea(area, 1);
  331.         area->CurLine = area->NbLine - 1;
  332.     }
  333.     else
  334.         area->CurLine++;
  335.  
  336.     area->CurCol = 0;
  337. }
  338.  
  339.  
  340. /****************************/
  341. /* ecrit une chaine clippée    */
  342. /****************************/
  343. PRIVATE VOID TextClip(struct TextArea *area, char *s, UWORD len)
  344. {
  345.     UWORD w, clen;
  346.  
  347.     while (len > 0)
  348.     {
  349.         if (area->CurLine >= area->NbLine)
  350.             LineFeed(area);
  351.  
  352.         w = GetCurrentWidth(area);
  353.         clen = ClipString(area->Font, s, len, w);
  354.         LowLevelText(area, s, clen);
  355.  
  356.         /* mise a jour du curseur */
  357.         if (area->Font->tf_Flags & FPF_PROPORTIONAL)
  358.             area->CurCol += StringLength(area->Font, s, clen);
  359.         else
  360.             area->CurCol += clen;
  361.  
  362.         /* mise a jour de la chaine */
  363.         len -= clen;
  364.         s += clen;
  365.         if ( (len > 0) AND (area->ClassFlags & TAF_CLIP_TEXT) )
  366.             LineFeed(area);
  367.         else
  368.             break;
  369.     }
  370. }
  371.  
  372.  
  373. /****************************/
  374. /* ecrit une chaine clippée    */
  375. /****************************/
  376. PRIVATE VOID LowLevelText(struct TextArea *area, char *s, UWORD len)
  377. {
  378.     struct RastPort *rp;
  379.     struct TextEnv env;
  380.  
  381.     rp = area->RPort;
  382.     SaveTextEnv(rp, &env);
  383.  
  384.     SetDrMd(rp, JAM2);
  385.     SetFont(rp, area->Font);
  386.     {
  387.         WORD x, y;
  388.  
  389.         y = area->TextBox.y + (area->CurLine * area->LineHeight);
  390.  
  391.         if (area->Font->tf_Flags & FPF_PROPORTIONAL)
  392.             x = area->TextBox.x + area->CurCol;
  393.         else
  394.             x = area->TextBox.x + area->CurCol * area->Font->tf_XSize;
  395.  
  396.         /* reecrire l'entree */
  397.         SetAPen(rp, area->FPen);
  398.         SetBPen(rp, area->BPen);
  399.         Move(rp, x, y + area->Font->tf_Baseline);
  400.         Text(rp, s, len);
  401.     }
  402.     RestoreTextEnv(rp, &env);
  403. }
  404.